home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_n_z.arj / VGAMOIRE.ASM < prev    next >
Assembly Source File  |  1989-03-09  |  8KB  |  473 lines

  1. ;    VGAMOIRE.COM
  2.  
  3. ; Structured pattern generator to show off the undocumented
  4. ; 320x400 256 color mode of the    IBM VGA as revealed by
  5. ; Michael Abrash in his    "On Graphics" column in the
  6. ; January/February 1989    issue of Programmer's Journal, Volume 7.1
  7.  
  8.  
  9. VGA_SEGMENT        equ    0A000h
  10. SC_INDEX        equ    3C4h
  11. GC_INDEX        equ    3CEh
  12. CRTC_INDEX        equ    3D4h
  13. MAP_MASK        equ    2
  14. MEMORY_MODE        equ    4
  15. MAX_SCAN_LINE        equ    9
  16. START_ADDRESS_HIGH    equ    0Ch
  17. UNDERLINE        equ    14h
  18. MODE_CONTROL        equ    17h
  19. READ_MAP        equ    4
  20. GRAPHICS_MODE        equ    5
  21. MISCELLANEOUS        equ    6
  22. SCREEN_WIDTH        equ    320
  23. SCREEN_HEIGHT        equ    400
  24.  
  25. tab            equ    9
  26. lf            equ    10
  27. cr            equ    13
  28.  
  29.  
  30. CONSTANT_TO_INDEXED_REGISTER    macro    ADDRESS, INDEX, VALUE
  31.     mov    dx, ADDRESS
  32.     mov    ax, (VALUE shl 8) + INDEX
  33.     out    dx, ax
  34.                 endm
  35.  
  36. code    segment
  37.     org    100h
  38.     assume    cs:code, ds:code
  39.  
  40.  
  41. Begin:
  42.  
  43.     push    cs
  44.     pop    ds
  45.  
  46.     mov    ax, VGA_SEGMENT
  47.     mov    es, ax
  48.  
  49.     call    Set320x400Mode
  50.  
  51.     mov    ah, 2Ch
  52.     int    21h
  53.     mov    Random, dx
  54.  
  55.     mov    si, 256        ; ColorCount
  56.  
  57.     call    Randy
  58.     mov    bp, ax
  59.     call    DoCircles
  60.     
  61. MainLoop:
  62.     call    MakeRandomPalette
  63.  
  64.     cmp    PageNo, 0
  65.     je    SetPage1
  66.     mov    ax, 0A800h
  67.     mov    es, ax
  68.     CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,0
  69.     mov    PageNo, 0
  70.     jmp    Start
  71. SetPage1:
  72.     mov    ax, 0A000h
  73.     mov    es, ax
  74.     CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,80h
  75.     mov    PageNo, 1
  76.  
  77. Start:
  78.     call    Randy
  79.     and    ax, 0003h
  80.     cmp    al, 0
  81.     je    Circ
  82.     cmp    al, 1
  83.     je    Sqar
  84.     cmp    al, 2
  85.     je    TiltCirc
  86.     jmp    TiltSqar
  87.  
  88. Circ:
  89.     call    Randy
  90.     inc    ax
  91.     mov    bp, ax
  92.     call    DoCircles
  93.     jmp    CheckKey
  94.  
  95. Sqar:
  96.     call    Randy
  97.     inc    ax
  98.     mov    bp, ax
  99.     call    DoSquares
  100.     jmp    CheckKey
  101.  
  102. TiltCirc:
  103.     call    Randy
  104.     inc    ax
  105.     mov    bp, ax
  106.     call    DoTiltCircles
  107.     jmp    CheckKey
  108.  
  109. TiltSqar:
  110.     call    Randy
  111.     inc    ax
  112.     mov    bp, ax
  113.     call    DoTiltSquares
  114.  
  115. CheckKey:
  116.     mov    ah, 0Bh
  117.     int    21h
  118.     cmp    al, 0
  119.     jne    GetOut
  120.     jmp    MainLoop
  121.  
  122. GetOut:
  123.     mov    ax, 0003h    ; Back to Text Mode
  124.     int    10h
  125.  
  126.     mov    ax, 4C00h
  127.     int    21h
  128.  
  129. PageNo        dw    1
  130.  
  131.  
  132. DoCircles        proc    near
  133.  
  134.     mov    bl, 00010001b    ; Plane Mask bit
  135.     mov    di, 0        ; Video memory pointer
  136.  
  137.     mov    cx, 0        ; For Y := 0 to 399 do
  138. ForYCirc:
  139.     push    cx
  140.     mov    cx, 0        ; For X := 0 to 319 do
  141. ForXCirc:
  142.     mov    ax, bp        ; Get IterateCnt
  143.     mul    cx        ; DX:AX := IterateCnt * X
  144.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * X)
  145.  
  146.     mov    dx, SC_INDEX    ; Select the correct plane
  147.     mov    ah, bl
  148.     mov    al, MAP_MASK
  149.     out    dx, ax
  150.  
  151.     mov    ax, si        ; Poke Color
  152.     mov    byte ptr es:[di], al
  153.  
  154.     rol    bl, 1        ; Rotate for next plane
  155.     cmp    bl, 00010001b    ; Did we rotate four times?
  156.     jne    DoNextXCirc    ; If not then do the next pixel
  157.     inc    di        ; Otherwise bump the Video MemPtr
  158.  
  159. DoNextXCirc:
  160.     inc    cx        ; Next X
  161.     cmp    cx, 320
  162.     jl    ForXCirc
  163.  
  164.     pop    cx
  165.  
  166.     mov    ax, bp        ; Get IterateCnt
  167.     mul    cx        ; DX:AX := IterateCnt * Y
  168.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * Y)
  169.  
  170.     inc    cx        ; Next Y
  171.     cmp    cx, 400
  172.     jl    ForYCirc
  173.  
  174.     ret
  175.  
  176. DoCircles        endp
  177.  
  178.  
  179. DoTiltCircles        proc    near
  180.  
  181.     mov    bl, 00010001b    ; Plane Mask bit
  182.     mov    di, 0        ; Video memory pointer
  183.  
  184.     mov    cx, 0        ; For Y := 0 to 399 do
  185. ForYTiltCirc:
  186.     push    cx
  187.     mov    cx, 0        ; For X := 0 to 319 do
  188. ForXTiltCirc:
  189.     mov    ax, bp        ; Get IterateCnt
  190.     mul    cx        ; DX:AX := IterateCnt * X
  191.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * X)
  192.  
  193.     mov    dx, SC_INDEX    ; Select the correct plane
  194.     mov    ah, bl
  195.     mov    al, MAP_MASK
  196.     out    dx, ax
  197.  
  198.     mov    ax, si        ; Poke Color
  199.     mov    byte ptr es:[di], al
  200.  
  201.     rol    bl, 1        ; Rotate for next plane
  202.     cmp    bl, 00010001b    ; Did we rotate four times?
  203.     jne    DoNextXTiltCirc    ; If not then do the next pixel
  204.     inc    di        ; Otherwise bump the Video MemPtr
  205.  
  206. DoNextXTiltCirc:
  207.     inc    cx        ; Next X
  208.     cmp    cx, 320
  209.     jl    ForXTiltCirc
  210.  
  211.     pop    cx
  212.  
  213.     mov    ax, bp        ; Get IterateCnt
  214.     mul    cx        ; DX:AX := IterateCnt * Y
  215.     sub    si, ax        ; ColorCount := ColorCount - (IterateCnt * Y)
  216.  
  217.     inc    cx        ; Next Y
  218.     cmp    cx, 400
  219.     jl    ForYTiltCirc
  220.  
  221.     ret
  222.  
  223. DoTiltCircles        endp
  224.  
  225.  
  226. DoSquares        proc    near
  227.  
  228.     mov    bl, 00010001b    ; Plane Mask bit
  229.     mov    di, 0        ; Video memory pointer
  230.  
  231.     mov    cx, 0        ; For Y := 0 to 399 do
  232. ForYSqr:
  233.     mov    CurrY, cx
  234.     push    cx
  235.     mov    cx, 0        ; For X := 0 to 319 do
  236. ForXSqr:
  237.     mov    CurrX, cx
  238.     mov    ax, bp        ; Get IterateCnt
  239.     mov    dx, CurrY    ; Get current Y
  240.     mul    dx        ; DX:AX := IterateCnt * Y
  241.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * Y)
  242.  
  243.     mov    dx, SC_INDEX    ; Select the correct plane
  244.     mov    ah, bl
  245.     mov    al, MAP_MASK
  246.     out    dx, ax
  247.  
  248.     mov    ax, si        ; Poke Color
  249.     mov    byte ptr es:[di], al
  250.  
  251.     rol    bl, 1        ; Rotate for next plane
  252.     cmp    bl, 00010001b    ; Did we rotate four times?
  253.     jne    DoNextXSqr    ; If not then do the next pixel
  254.     inc    di        ; Otherwise bump the Video MemPtr
  255.  
  256. DoNextXSqr:
  257.     inc    cx        ; Next X
  258.     cmp    cx, 320
  259.     jl    ForXSqr
  260.  
  261.     pop    cx
  262.  
  263.     mov    ax, bp        ; Get IterateCnt
  264.     mov    dx, CurrX    ; Get current X
  265.     mul    dx        ; DX:AX := IterateCnt * X
  266.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * X)
  267.  
  268.     inc    cx        ; Next Y
  269.     cmp    cx, 400
  270.     jl    ForYSqr
  271.  
  272.     ret
  273.  
  274. CurrX        dw    (?)
  275. CurrY        dw    (?)
  276.  
  277. DoSquares        endp
  278.  
  279.  
  280. DoTiltSquares        proc    near
  281.  
  282.     mov    bl, 00010001b    ; Plane Mask bit
  283.     mov    di, 0        ; Video memory pointer
  284.  
  285.     mov    cx, 0        ; For Y := 0 to 399 do
  286. ForYTiltSqr:
  287.     mov    CurrTiltY, cx
  288.     push    cx
  289.     mov    cx, 0        ; For X := 0 to 319 do
  290. ForXTiltSqr:
  291.     mov    CurrTiltX, cx
  292.     mov    ax, bp        ; Get IterateCnt
  293.     mov    dx, CurrTiltY    ; Get current Y
  294.     mul    dx        ; DX:AX := IterateCnt * Y
  295.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * Y)
  296.  
  297.     mov    dx, SC_INDEX    ; Select the correct plane
  298.     mov    ah, bl
  299.     mov    al, MAP_MASK
  300.     out    dx, ax
  301.  
  302.     mov    ax, si        ; Poke Color
  303.     mov    byte ptr es:[di], al
  304.  
  305.     rol    bl, 1        ; Rotate for next plane
  306.     cmp    bl, 00010001b    ; Did we rotate four times?
  307.     jne    DoNextXTiltSqr    ; If not then do the next pixel
  308.     inc    di        ; Otherwise bump the Video MemPtr
  309.  
  310. DoNextXTiltSqr:
  311.     inc    cx        ; Next X
  312.     cmp    cx, 320
  313.     jl    ForXTiltSqr
  314.  
  315.     pop    cx
  316.  
  317.     mov    ax, bp        ; Get IterateCnt
  318.     mov    dx, CurrTiltX    ; Get current X
  319.     mul    dx        ; DX:AX := IterateCnt * X
  320.     add    si, ax        ; ColorCount := ColorCount + (IterateCnt * X)
  321.  
  322.     inc    cx        ; Next Y
  323.     cmp    cx, 400
  324.     jl    ForYTiltSqr
  325.  
  326.     ret
  327.  
  328. CurrTiltX    dw    (?)
  329. CurrTiltY    dw    (?)
  330.  
  331. DoTiltSquares        endp
  332.  
  333.  
  334. Randy            proc    near
  335.  
  336. ;    Returns a pseudo random integer in AX
  337.  
  338. GetTime:
  339.     mov    ah, 2Ch
  340.     int    21h
  341.  
  342.     mov    ax, Random
  343.     add    ax, 13
  344.     mul    dx
  345.     add    dx, 23
  346.     mul    dx
  347.     shr    dx, 1
  348.     shr    dx, 1
  349.     shr    dx, 1
  350.     add    ax, dx
  351.     and    ax, 7FFFh
  352.     mov    Random, ax
  353.  
  354.     ret
  355.  
  356. Random    dw    (?)
  357.  
  358. Randy            endp
  359.     
  360.  
  361. MakeRandomPalette    proc    near
  362.  
  363.     call    Randy
  364.     mov    byte ptr RED, al
  365.     call    Randy
  366.     mov    byte ptr GREEN, al
  367.     call    Randy
  368.     mov    byte ptr BLUE, al
  369.  
  370.     mov    cx, 0
  371. NextPal:
  372.     mov    al, cl
  373.     mov    dx, 03C8h    ; Set Write PEL Address
  374.     out    dx, al
  375.     inc    dx
  376.  
  377.     mov    al, byte ptr RED    ; Get RED
  378.     and    al, 3Fh
  379.     out    dx, al
  380.  
  381.     mov    al, byte ptr GREEN    ; Get GREEN
  382.     and    al, 3Fh
  383.     out    dx, al
  384.  
  385.     mov    al, byte ptr BLUE    ; Get BLUE
  386.     and    al, 3Fh
  387.     out    dx, al
  388.  
  389.     inc    byte ptr RED
  390.     inc    byte ptr GREEN
  391.     inc    byte ptr BLUE
  392.     inc    cx
  393.     cmp    cx, 256
  394.     jl    NextPal
  395.  
  396.     ret
  397.  
  398. RED    db    (?)
  399. GREEN    db    (?)
  400. BLUE    db    (?)
  401.  
  402. MakeRandomPalette        endp
  403.  
  404.  
  405. Set320x400Mode        proc    near
  406.  
  407.     mov    ax, 0013h
  408.     int    10h
  409.  
  410.     mov    dx, SC_INDEX
  411.     mov    al, MEMORY_MODE
  412.     out    dx, al
  413.     inc     dx
  414.     in    al, dx
  415.     and     al, NOT 08h
  416.     or    al, 04h
  417.     out    dx, al
  418.     mov     dx, GC_INDEX
  419.     mov     al, GRAPHICS_MODE
  420.     out    dx, al
  421.     inc     dx
  422.     in    al, dx
  423.     and    al, NOT 10h
  424.     out    dx, al
  425.     dec    dx
  426.     mov    al, MISCELLANEOUS
  427.     out    dx, al
  428.     inc    dx
  429.     in    al, dx
  430.     and    al, NOT 02h
  431.     out    dx, al
  432.  
  433.     CONSTANT_TO_INDEXED_REGISTER  SC_INDEX, MAP_MASK, 0Fh
  434.  
  435.     mov    ax, VGA_SEGMENT
  436.     mov    es, ax
  437.     sub    di, di
  438.     mov    ax, di
  439.     mov    cx, 8000h
  440.     rep    stosw
  441.  
  442.     mov    dx, CRTC_INDEX
  443.     mov    al, MAX_SCAN_LINE
  444.     out    dx, al
  445.     inc    dx
  446.     in    al, dx
  447.     and    al, NOT 1Fh
  448.     out    dx, al
  449.     dec    dx
  450.  
  451.     mov    al, UNDERLINE
  452.     out    dx, al
  453.     inc    dx
  454.     in    al, dx
  455.     and    al, NOT 40h
  456.     out    dx, al
  457.     dec    dx
  458.     mov    al, MODE_CONTROL
  459.     out    dx, al
  460.     inc    dx
  461.     in    al, dx
  462.     or    al, 40h
  463.     out    dx, al
  464.  
  465.     ret
  466.  
  467. Set320x400Mode        endp
  468.  
  469.  
  470. code    ends
  471.  
  472. End    Begin
  473.